const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const db = require('../config/database');
const dayjs = require('dayjs');

const authenticateToken = (req, res, next) => {
    // 从请求头中获取 token
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

    if (!token) {
        return res.status(401).json({
            success: false,
            code: 401,
            message: '未提供认证令牌'
        });
    }

    // 验证 token
    jwt.verify(token, 'crm', (err, user) => {
        if (err) {
            // 根据不同错误返回不同信息
            if (err.name === 'TokenExpiredError') {
                return res.json({
                    code: 403,
                    success: false,
                    message: '令牌已过期'
                });
            }
            return res.json({
                code: 403,
                success: false,
                message: '无效的令牌'
            });
        }

        // 将用户信息附加到请求对象上
        req.user = user;
        next(); // 继续处理请求
    });
}


const encryptPhone = (phone) => {
    // 使用固定的密钥和IV，确保加密和解密使用相同的值
    const key = Buffer.from('12345678901234567890123456789012', 'utf8'); // 32字节固定密钥
    const iv = Buffer.from('1234567890123456', 'utf8');  // 16字节固定IV
    const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
    let encrypted = cipher.update(phone, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    return encrypted;
}

const decryptPhone = (encrypted) => {
    // 使用与加密相同的固定密钥和IV
    const key = Buffer.from('12345678901234567890123456789012', 'utf8'); // 32字节固定密钥
    const iv = Buffer.from('1234567890123456', 'utf8');  // 16字节固定IV
    const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
    let decrypted = decipher.update(encrypted, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}

const extractNumber = (str) => {
    const match = str.match(/\d+/); // 匹配一个或多个连续数字
    return match ? parseInt(match[0], 10) : null;
}

const generateString = (prefix, number, length) => {
    if (String(number).length > length) {
        return `${prefix}${String(number)}`;
    }
    if (String(number).length < length) {
        return `${prefix}${'0'.repeat(length - String(number).length)}${String(number)}`;
    }
    return `${prefix}${number}`;
}

const getNextId = async (prefix, IdName, table, length) => {
    let nextId = 1;
    const [result] = await db.execute(`SELECT MAX(${IdName}) AS max_id FROM ${table}`);
    if (result[0].max_id) {
        const currentNumber = extractNumber(result[0].max_id);
        nextId = currentNumber + 1;
    }
    return generateString(prefix, nextId, length);
}

// 记录用户操作日志
const logUserOperation = async (req, operationType, operationModule, operationDesc, status = '成功', errorMessage = null) => {

    try {
        const username = req.user.userId || 'unknown';
        // const ipAddress = req.ip || req.connection.remoteAddress || req.headers['x-forwarded-for'];
        const ipAddress = req.rawHeaders[1]
        const userAgent = req.headers['user-agent'];
        const logId = await getNextId('LOG', 'log_id', 'user_ctrl_log', 5);
        const operationTime = dayjs().format('YYYY-MM-DD HH:mm:ss');

        const sql = `
            INSERT INTO user_ctrl_log 
            (log_id, username, operation_type, operation_module, operation_desc, ip_address, user_agent, operation_time, status, error_message) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        `;

        // 打印日志
        console.log(logId, username, operationType, operationModule, operationDesc, ipAddress, userAgent, operationTime, status, errorMessage);

        await db.execute(sql, [
            logId,
            username,
            operationType,
            operationModule,
            operationDesc,
            ipAddress,
            userAgent,
            operationTime,
            status,
            errorMessage
        ]);

        return 'success'
    } catch (error) {
        console.error('记录用户操作日志失败:', error);
        return 'error'
    }
}

module.exports = {
    // 验证token
    authenticateToken,

    // 手机号对称加密
    encryptPhone,

    // 手机号对称解密
    decryptPhone,

    // 提取字符串中的数字
    extractNumber,

    // 生成一串字符串 参数: 前缀 , 数字, 长度
    // 例如: generateString('TY', 1, 5) 返回: TY00001
    // 例如: generateString('TY', 10, 5) 返回: TY00010
    // 例如: generateString('TY', 100, 5) 返回: TY00100
    generateString,

    // 获取下一个ID
    getNextId,

    // 记录用户操作日志
    logUserOperation,
};